#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

/*
Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=1205
*/
string solution(vector<string> dictionary, const string &word) {
  do {
    bool is_match = true;

    for (int i = 0; i < word.size(); ++i) {
      // 在 next_permutation 返回的新组合中，我们都用下面这样的方式去匹配单词
      // dictionary[0] 匹配 word[0]
      // dictionary[1] 匹配 word[1]
      // dictionary[2] 匹配 word[2]
      // dictionary[3] 匹配 word[3]
      // 当 next_permutation 枚举了所有可能的情况之后，我们就知道是不是能匹配单词了。
      is_match = find(
        dictionary[i].begin(), dictionary[i].end(), word[i]
      ) != dictionary[i].end();

      if (!is_match) { break; }
    }
    
    if (is_match) {
      return "YES";
    }
  } while (next_permutation(dictionary.begin(), dictionary.end()));
  // 上面，每次调用 next_permutation 都会返回一个新的骰子组合
  // Because next_permutation modifies the order of dictionary and this order
  // can affect the matching result, we must pass dictionary by value.
  return "NO";
}

int main(int argc, char const *argv[])
{
  int words = 0;
  cin >> words;

  // 实际上，这里我们没必要把每个骰子存成 set<char>，
  // 直接存成 string 就好了。
  // 因为稍后比较的时候，我们用专门用一个位置上的骰子匹配一个位置上的字符
  // 不存在用同一个骰子多个面的情况。
  vector<string> blocks(4, "");
  
  for (int i = 0; i < 4; ++i) {
    cin >> blocks[i];
  }

  // 为了使用 next_permutation，我们要把 blocks 先排序
  // blocks 中的元素类型是 string，因此排序后，字母小的骰子会排在前面。
  sort(blocks.begin(), blocks.end());

  while (words != 0) {
    string word;
    cin >> word;

    cout << solution(blocks, word) << endl;
    --words;
  }

  return 0;
}
